#include "imagerecover.h"
#include "qimage.h"
#include "qjsonarray.h"
#include "onewayfunction.h"
#include "steganographyOnImage.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QFile>

imageRecover::imageRecover(std::shared_ptr<EC_GROUP> group)
    :m_group(group)
    ,m_point(group)
{

}

bool imageRecover::setPubInfo(QString pubInfoFileName, void (*logFun)(QString))
{
    QFile jsonFile{pubInfoFileName};
    if (!jsonFile.open(QIODevice::ReadOnly)&&logFun) {
        logFun("Failed to open file:"+pubInfoFileName);
        return false;
    }
    QByteArray json = jsonFile.readAll();
    jsonFile.close();
    QJsonParseError error;
    QJsonDocument doc=QJsonDocument::fromJson(json,&error);
    if (doc.isNull()&&logFun) {
        logFun("Failed to parse JSON:" + error.errorString());
        return false;
    }
    m_obj = doc.object();
    m_N = m_obj.value("m_N").toInt();//秘密图像分组数
    m_k = m_obj.value("m_k").toInt();//每组秘密的每个子秘密的像素个数
    m_dep=m_obj.value("depth").toInt();//位深
    if(m_N==0 or m_k==0 or m_dep==0){return false;}//
    return true;
}

QByteArrayList imageRecover::getFrx(int setNum, QString imageFileName,SaveMethod method)
{
    if(m_obj.isEmpty()){
        return QByteArrayList();
    }//公共信息打开失败
    if(m_N==0 or m_k==0 or m_dep==0){return QByteArrayList();}
    QString key = QString(QString("setR")+QString::number(setNum));
    if(key.isEmpty()){return QByteArrayList();}//公共信息没有编号为setNum的授权集合
    uchar* data=0;
    QImage image{imageFileName};
    int xlen = m_k*m_dep/8;//每个子秘密的字节数
    QJsonArray setrT = m_obj.value(key).toArray();
    int r = setrT[0].toInt();//授权集合标识
    QByteArrayList ans{m_N};
    QByteArray shadow;
    int dataLen=0;
    switch (method) {
    case SaveMethod::LSB:
    case SaveMethod::EMD:
        shadow=SteganographyOnImage::retrieval(image);
        data=(uchar*)shadow.data();
        dataLen=shadow.size();
        break;
    case IMA:
        data = image.bits();
        dataLen=image.sizeInBytes();
        break;
    case TXT:
    {
        QFile file{imageFileName};
        file.open(QIODevice::ReadWrite);
        shadow=file.readAll();
        file.close();
        data=(uchar*)shadow.data();
        dataLen=shadow.size();
        break;
    }
    default:
        return QByteArrayList();
    }
    if(!data||dataLen<m_N*xlen){
        return QByteArrayList();
    }
    MyBIGNUM bigNumX;
    for(int i=0; i<m_N; ++i){
        bigNumX.setNumFromUChar(data,xlen);
        data+=xlen;
        auto data_i=OneWayFunction::ecFunc(r,bigNumX,m_point,m_group.get());
        ans[i]=std::move(data_i);
    }
    return ans;
}

QByteArrayList imageRecover::splitImage(uchar* data, int w,int n)
{
    QByteArrayList ret{n};
    for(int i=0;i<n;i++){
        ret[i]=QByteArray((char*)data,w);
        data+=w;
    }
    return ret;
}
